/**
 * Sample Skeleton for "SalaryDisplayAttendance.fxml" Controller Class
 * You can copy and paste this code into your favorite IDE
 **/

package com.pentofab.payrollmanagement.ui.controller;

import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.ResourceBundle;

import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.concurrent.Task;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.util.Callback;

import com.pentofab.payrollmanagement.application.PayrollApplicationFactory;
import com.pentofab.payrollmanagement.dao.EmployeeDao;
import com.pentofab.payrollmanagement.dao.SalaryDAO;
import com.pentofab.payrollmanagement.dao.model.AttendanceLeaveDetail;
import com.pentofab.payrollmanagement.dao.model.Company;
import com.pentofab.payrollmanagement.dao.model.Department;
import com.pentofab.payrollmanagement.dao.model.SalaryStracture;
import com.pentofab.payrollmanagement.dao.model.Units;
import com.pentofab.payrollmanagement.dao.model.UserAccounts;
import com.pentofab.payrollmanagement.utilities.PayRollUtility;


public class SalaryReportController extends AbstractUIController implements FormValidator,
     Initializable {

    @FXML
    private GridPane grid;
    @FXML
    private ChoiceBox<String> month;
    @FXML
    private ChoiceBox<String> year;
    @FXML
    private TableView<ObservableList<StringProperty>> tableView;
    @FXML
    private ChoiceBox<String> department;
	@FXML
    private ChoiceBox<String> companyBox;
	@FXML
    private ChoiceBox<String> unitBox;
	@FXML
    private TextField  empIdField;
	
	
    private Company company;
    private UserAccounts userAccounts;
    private TableColumn<AttendanceLeaveDetail, String>[] tableColmns = null;
    SalaryDAO salaryDAO = PayrollApplicationFactory.getSalaryDAO();
    ScrollPane scrollpane1 = new ScrollPane(); 
    EmployeeDao employeeDao = PayrollApplicationFactory.getEmployeeMgmt();
    
    public void view() {
    	
    	scrollpane1.setContent(tableView);
    	String validationMsg = getValidationMessage();
    	if(!validationMsg.equals("")){
    		showError(validationMsg);
    		return;
    	}
    	
    	try {
    		
    	String selyear = year.getSelectionModel().getSelectedItem();
    	int selectedMonths = month.getSelectionModel().getSelectedIndex();
    	int maxDay  = PayRollUtility.getMaxDayofMonth(Integer.parseInt(selyear), selectedMonths);
    	
    	
    	String from_date = "01-"+(selectedMonths+1)+"-"+selyear;
    	String to_date = maxDay+"-"+(selectedMonths+1)+"-"+selyear;		
    	
    	String departmentCode = department.getSelectionModel().getSelectedItem();
		String companyCode = companyBox.getSelectionModel().getSelectedItem();
		String unitCode = unitBox.getSelectionModel().getSelectedItem();
		
		if(companyCode !=null){
		
			companyCode = companyCode.substring(0,companyCode.indexOf(":")).trim();
		}
		
		if(unitCode != null){
		
			unitCode = unitCode.substring(0,unitCode.indexOf(":")).trim();
		}
		
		if(departmentCode != null){
		
			departmentCode = departmentCode.substring(0,departmentCode.indexOf(":")).trim();
		}
    		
    		tableView.setEditable(false);
    	    tableView.getItems().clear();
    	    tableView.getColumns().clear();
    	    
    	    String empId = empIdField.getText().trim().equals("") ? null :  empIdField.getText().trim();
    	    
    	  if(PayRollUtility.isPreviousMonth(from_date)){
    		  
    		 PayRollUtility.debug("Getting datafor previous monhs from repository computation not required.");
    		  HashMap<String, String> slaryInfo = salaryDAO.getComputedSalary(empId, String.valueOf(selectedMonths+1), selyear, 
    				  companyCode, departmentCode, unitCode, null);
    		  if(slaryInfo == null || slaryInfo.size() ==0){
    			  
    			  tableView.getItems().clear();
    			  return;
    		  }
    		  
    		  populateTablebyExistingData(slaryInfo);
    	  }else{
    		  HashMap<String, SalaryStracture> empSalInfoMap = salaryDAO.computeSalaryForMonth(from_date, to_date, empId, 
    				  companyCode,unitCode, departmentCode, selyear, selectedMonths+1);
    		  
    		  if(empSalInfoMap == null || empSalInfoMap.size() ==0){
    			  
    			  tableView.getItems().clear();
    			  return;
    		  }
    		  
    		  populateTable(empSalInfoMap);
    	  }

    	} catch (Exception e) {
			e.printStackTrace();
		}
    	
    		
    
    }

    private void populateTable(final HashMap<String, SalaryStracture> empSalInfoMap ) {
    	
    	    System.out.println("====================== entering populateTable in =================================");
    	    
    	    
    	    final String header = "ID,Name,Company,Dept,Unit,Design,ESI Number,PF Number,MaxDays,Paid Days,Gross, Basic,"
    				+ "HRA,Conveyance,Special,Medic,Others,INCENTIVE,PF,ESI,PTax,LOP,Earnings,DECUCATION,NetPay";
    	    Task<Void> task = new Task<Void>() {
    	      @Override
    	      protected Void call() throws Exception {
    	        if (true) {
    	          final String headerLine =header.toString();
    	          final String[] headerValues = headerLine.split(",");
    	          Platform.runLater(new Runnable() {
    	            @Override
    	            public void run() {
    	              for (int column = 0; column < headerValues.length; column++) {
    	            	  tableView.getColumns().add(
    	                    createColumn(column, headerValues[column].trim()));
    	              }
    	            }
    	          });
    	        }

    	        
    	       
    	        
    	        Iterator<String> salaryInfoListIterator  = empSalInfoMap.keySet().iterator();
    	        while (salaryInfoListIterator.hasNext()) {
    	        	
    	        	String currentEmpId = salaryInfoListIterator.next();
    	        	
    	        	SalaryStracture current = empSalInfoMap.get(currentEmpId);
    	        	String[] colnms = header.split(",");
    	        	

    	        	StringBuffer rowData = new StringBuffer();
    	        	rowData.append(current.getEmployee().getEmpId()+",");
    	        	rowData.append(current.getEmployee().getEmpName()+",");
    	        	rowData.append(current.getEmployee().getCompany().getCompanyID()+",");
    	        	rowData.append(current.getEmployee().getDepertment().getCode()+",");
    	        	rowData.append(current.getEmployee().getUnit()+",");
    	        	rowData.append(current.getEmployee().getDesignation().getCode()+",");
    	        	rowData.append(current.getEsiNumber()+",");
    	        	rowData.append(current.getPfNumber()+",");
    	        	rowData.append(current.getMaxDays()+",");
    	        	rowData.append(current.getPaidDays()+",");
    	        	rowData.append(current.getGrossSalary()+",");
    	        	rowData.append(current.getBasic()+",");
    	        	rowData.append(current.getHra()+",");
    	        	rowData.append(current.getConveyance()+",");
    	        	rowData.append(current.getSpecialAllowance()+",");
    	        	rowData.append(current.getMedicalAllowance()+",");
    	        	rowData.append(current.getOthers()+",");
    	        	rowData.append(current.getIncentive()+",");
    	        	rowData.append(current.getPfAmt()+",");
    	        	rowData.append(current.getEsiAmt()+",");
    	        	rowData.append(current.getPtAmount()+",");
    	        	rowData.append(current.getLop()+",");
    	        	rowData.append(current.getTotalEarnigs()+",");
    	        	rowData.append(current.getTotalDesctions()+",");
    	        	rowData.append(current.getNetPay());
    	        	
    	        	

    	        	final String[] dataValues = rowData.toString().split(",");
    	        	Platform.runLater(new Runnable() {
    	        		@Override
    	        		public void run() {
    	        			// Add additional columns if necessary:
    	        			for (int columnIndex = tableView.getColumns().size(); columnIndex < dataValues.length; columnIndex++) {
    	        				tableView.getColumns().add(createColumn(columnIndex, ""));
    	        			}
    	        			// Add data to table:
    	        			ObservableList<StringProperty> data = FXCollections.observableArrayList();
    	        			for (String value : dataValues) {
    	        				data.add(new SimpleStringProperty(value));
    	        			}
    	        			tableView.getItems().add(data);
    	        		}
    	        	});
    	        }
    	        return null;
    	      }
    	    };
    	    Thread thread = new Thread(task);
    	    thread.setDaemon(true);
    	    thread.start();
    	    thread.run();
    	    
    	    System.out.println("====================== entering populateTable out =================================");
    	  }
    
    private void populateTablebyExistingData(final HashMap<String, String> empSalInfoMap ) {
    	
	    System.out.println("====================== entering populateTable in =================================");
	    System.out.println("empSalInfoMap : "+empSalInfoMap);
	    
	    final String header = "ID,Name,Company,Dept,Unit,Design,ESI Number,PF Number,MaxDays,Paid Days,Gross, Basic,"
				+ "HRA,Conveyance,Special,Medic,Others,INCENTIVE,PF,ESI,PTax,LOP,Earnings,DECUCATION,NetPay";
	    Task<Void> task = new Task<Void>() {
	      @Override
	      protected Void call() throws Exception {
	        if (true) {
	          final String headerLine =header.toString();
	          final String[] headerValues = headerLine.split(",");
	          Platform.runLater(new Runnable() {
	            @Override
	            public void run() {
	              for (int column = 0; column < headerValues.length; column++) {
	            	  tableView.getColumns().add(
	                    createColumn(column, headerValues[column].trim()));
	              }
	            }
	          });
	        }

	        
	       
	        
	        Iterator<String> salaryInfoListIterator  = empSalInfoMap.keySet().iterator();
	        while (salaryInfoListIterator.hasNext()) {
	        	
	        	String currentEmpId = salaryInfoListIterator.next();
	        	
	        	String currentEmpSalData = empSalInfoMap.get(currentEmpId);
	        	String[] colnms = header.split(",");
	        	
	        	

	        	final String[] dataValues = currentEmpSalData.split(",");
	        	Platform.runLater(new Runnable() {
	        		@Override
	        		public void run() {
	        			// Add additional columns if necessary:
	        			for (int columnIndex = tableView.getColumns().size(); columnIndex < dataValues.length; columnIndex++) {
	        				tableView.getColumns().add(createColumn(columnIndex, ""));
	        			}
	        			// Add data to table:
	        			ObservableList<StringProperty> data = FXCollections.observableArrayList();
	        			for (String value : dataValues) {
	        				data.add(new SimpleStringProperty(value));
	        			}
	        			tableView.getItems().add(data);
	        		}
	        	});
	        }
	        return null;
	      }
	    };
	    Thread thread = new Thread(task);
	    thread.setDaemon(true);
	    thread.start();
	    thread.run();
	    
	    System.out.println("====================== entering populateTable out =================================");
	  }

    private TableColumn<ObservableList<StringProperty>, String> createColumn(
    	      final int columnIndex, String columnTitle) {
    	    TableColumn<ObservableList<StringProperty>, String> column = new TableColumn<ObservableList<StringProperty>, String>();
    	    String title;
    	    if (columnTitle == null || columnTitle.trim().length() == 0) {
    	      title = "Column " + (columnIndex + 1);
    	    } else {
    	      title = columnTitle;
    	    }
    	    column.setText(title);
    	    column.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<ObservableList<StringProperty>, String>, ObservableValue<String>>() {
    	          @Override
    	          public ObservableValue<String> call(
    	              CellDataFeatures<ObservableList<StringProperty>, String> cellDataFeatures) {
    	            ObservableList<StringProperty> values = cellDataFeatures.getValue();
    	            if (columnIndex >= values.size()) {
    	              return new SimpleStringProperty("");
    	            } else {
    	              return cellDataFeatures.getValue().get(columnIndex);
    	            }
    	          }
    	        });
    	    
    	    if(columnIndex >3){
    	    	column.setSortable(false);
    	    }
    	    column.setEditable(false);
    	    column.resizableProperty().set(false);
    	    return column;
    	  }
    
	public void initialize(URL fxmlFileLocation, ResourceBundle resources) {
    	
    	year.getSelectionModel().selectedIndexProperty()
		.addListener(new ChangeListener<Number>() {

			@Override
			public void changed(ObservableValue arg0, Number arg1,
					Number arg2) {

				month.getSelectionModel().clearSelection();
			}

		});
    	
    	companyBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {

			@Override
			public void changed(ObservableValue arg0, String arg1,
					String arg2) {

				try {
				department.getItems().clear();
				unitBox.getItems().clear();
				ArrayList<Department> departments;
					String companyCode = companyBox.getSelectionModel().getSelectedItem();
					if(companyCode == null){
						return;
					}
					PayRollUtility.debug("companyCode : "+companyCode);
					companyCode = companyCode.substring(0,companyCode.indexOf(":"));

					departments = (ArrayList<Department>) employeeDao.getAllDepartments(companyCode);
					
					Iterator<Department> departmentiIterator = departments.listIterator();
					while(departmentiIterator.hasNext()){
						Department dept = departmentiIterator.next();
						department.getItems().add(dept.getCode()+":"+dept.getDescription());
					}
					
					
					ArrayList<Units> unitList =  (ArrayList<Units>) employeeDao.getUnits(companyCode);
					Iterator<Units> unitListIterator = unitList.listIterator();
					while(unitListIterator.hasNext()){
						Units unit = unitListIterator.next();
						unitBox.getItems().add(unit.getUnitId()+":"+unit.getName());
					}

				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		});

    }

    public void goBack() {

		if (getParent() != null && getParent().length() > 0) {
			PayrollApplicationFactory.getMainController().showScreen(
					getParent(), false);
		}
	
	}
    
    public void reset() {
    	
  		refreshUI();
  	
  	}
	@Override
	public boolean isValid() {
		return false;
	}

	@Override
	public String getValidationMessage() {
		
		if(year.getSelectionModel().getSelectedIndex() < 0)
		return UIMessages.FROM_YEAR;
		
		if(month.getSelectionModel().getSelectedIndex() < 0)
		return UIMessages.FROM_YEAR;
		return "";
	}

	@Override
	public Parent getView() {
		return grid;
	}

	@Override
	public String getTitle() {
		return "Consilidated Attendance";
	}

	@Override
	public void refreshUI(Object... args) {
		
		 tableView.getItems().clear();
 	     tableView.getColumns().clear();

 	     if (args != null && args.length > 0) {
			Company company = (Company) args[0];
			this.company = company;
			
			if(args.length > 1 && args[1] instanceof UserAccounts){
				userAccounts = (UserAccounts) args[1];
			}
		}
		tableView.getItems().clear();
		this.year.getItems().clear();
		month.getSelectionModel().clearSelection();
		year.getSelectionModel().clearSelection();
		ArrayList<String> yearList = new ArrayList<String>();
		int year = PayRollUtility.getYear() - 1;
		for (int i = 0; i < 5; i++) {
			yearList.add(year + "");
			year++;
		}
		year = PayRollUtility.getYear();
		this.year.getItems().addAll(yearList);
		
		companyBox.getItems().clear();
		department.getItems().clear();
		unitBox.getItems().clear();
		
		try{	
			ArrayList<Company> companyList =  (ArrayList<Company>) employeeDao.getCompanies();
			Iterator<Company> companyListIterator = companyList.listIterator();
			while(companyListIterator.hasNext()){
				Company comp = companyListIterator.next();
				companyBox.getItems().add(comp.getCompanyID()+":"+comp.getName());
			}
			
		}catch(Exception e){
			e.printStackTrace();
			showError(e.getMessage());
		}
		
	}

	
}
